package fast.loader;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

import fast.data.RandomSuffix;
import fast.data.Stat;

import au.com.bytecode.opencsv.CSVReader;

public class ItemUpgrade {
	
	private static CSVReader reader = null;
	public HashMap<Integer,String[]> item_data = read("static/item_data.csv",0);
	//public HashMap<Integer,String[]> item_data_new = read("static/item_data_new.csv",0);
	public HashMap<Integer,String[]> item_damage_one_hand = read("static/ItemDamageOneHand.dbc.csv",0);
	public HashMap<Integer,String[]> ruleset_item_upgrade = null; // read("static/RulesetItemUpgrade.db2.csv",3);
	public HashMap<Integer,String[]> random_prop_points = read("static/RandomPropPoints.dbc.csv",0);
	
	double ITEM_SOCKET_COST = 160.0;
	
	public ItemUpgrade(){
		
	}
	
	private static String format(String input){
		return input.replace("\"", "").replace("{", "").replace("}", "").trim();
	}
	
	public static HashMap<Integer,String[]> read(String file,int field){
		HashMap<Integer,String[]> data = new HashMap<Integer,String[]>();
		try {
			reader = new CSVReader(new FileReader(file));
			String[] nextLine = null;
			while ((nextLine = reader.readNext()) != null) {
				if(nextLine.length == 1) continue;
				nextLine[field] = format(nextLine[field]);
		        data.put(Integer.parseInt(nextLine[field]),nextLine);
		    }
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}
	
	// working
	public void populate_item_upgrade_level_2(Item item){ 
	    String[] row = item_data.get(item.getId());
	    if(row == null){
	      //System.out.println("no item data found");
	      return;
	    }
	    String[] base = random_prop_points.get(item.getItemLevel());
	    
	    for(int i = 0;i< row.length;i++){
	    	row[i] = format(row[i]);
	    	//System.out.println(i + " " + row[i]);
	    }
	
	    //self.stats = {}
	    for(int i = 0;i < 10; i++){
	    	if (row[17+i].equals("-1"))
	    		break;
	      
			int enchantid = Integer.parseInt(row[17+i]);
			double multiplier = Double.parseDouble(row[37+i]);
			double socket_mult = Double.parseDouble(row[47+i]);
			// basevalue = base[1+quality_index(self.quality)*5+slot_index(equip_location)]
			//double basevalue = base[ItemSuffixDB.QualityIndex(item.getQuality())][ItemSuffixDB.SlotIndex(item.getInventorySlot())];
			double basevalue = Integer.parseInt(base[1+ItemSuffixDB.QualityIndex(item.getQuality()) * 5 + ItemSuffixDB.SlotIndex(item.getInventorySlot())]);
			if(enchantid != 0){
				int statid = enchantid;
				double value2 = (multiplier/10000.0) * basevalue - socket_mult * ITEM_SOCKET_COST;
				int value = (int) Math.round(value2);
				Stat stat = getStat(statid);
				//System.out.println(stat + " " + value);
				item.setStat(stat, value);
			}
	    }
	    // if weapon, update dps
	    if(item.getSpeed() != 0.0){
	    	String[] row2 = item_damage_one_hand.get(item.getItemLevel());
	    	item.setDps(Double.parseDouble(row2[1+item.getQuality()])); // TODO validate if we are accessing the correct column
	    }
	}
	
	public void populate_item_upgrade_level(Item item){ 
	    String[] row = item_data.get(item.getId());
	    if(row == null){
	      //System.out.println("no item data found");
	      return;
	    }
	    int[][] base = RandomSuffix.RandomPropData[item.getItemLevel()-277];
	    //base = rand_prop_points[self.ilevel.to_s]
	    int[][] ori_base = RandomSuffix.RandomPropData[item.getOriginalItemLevel()-277];
	
	    //self.stats = {}
	    for(int i = 0;i < 10; i++){
	      if (row[17+i].equals("-1"))
	      	break;
	      
	      int enchantid = Integer.parseInt(row[17+i]);
	      double multiplier = Double.parseDouble(row[37+i]);
	      double socket_mult = Double.parseDouble(row[47+i]);
	      double basevalue = base[ItemSuffixDB.QualityIndex(item.getQuality())][ItemSuffixDB.SlotIndex(item.getInventorySlot())];
	      double ori_basevalue = ori_base[ItemSuffixDB.QualityIndex(item.getQuality())][ItemSuffixDB.SlotIndex(item.getInventorySlot())];
	      if(enchantid != 0){
			int statid = enchantid;
			double value2 = (multiplier/10000.0) * basevalue - socket_mult * ITEM_SOCKET_COST * ( basevalue / ori_basevalue );
			int value = (int) Math.round(value2);
			Stat stat = getStat(statid);
			
			item.setStat(stat, value);
	      }
	    }
	    // if weapon, update dps
	    String[] row2 = item_damage_one_hand.get(item.getItemLevel());
	    if(item.getSpeed() != 0.0)
	    	item.setDps(Double.parseDouble(row2[1+item.getQuality()])); // TODO validate if we are accessing the correct column
	}
	
	private Stat getStat(int id)
    {
		switch (id)
        {
            case 3:
                return Stat.agi;
            case 7:
                return Stat.sta;
            case 5:
                return Stat.intt;
            case 4:
                return Stat.str;
            case 6:
                return Stat.spi;
            case 13:
            	return Stat.dodge;
            case 32:
                return Stat.cri;
            case 36:
                return Stat.hst;
            case 31:
                return Stat.hit;
            case 35:
            	return Stat.res;
            case 37:
                return Stat.exp;
            case 45:
            	return Stat.sp;
            case 49:
                return Stat.mst;
            case 57:
            	return Stat.pvppower;
        }
        new Exception("Statid not found: " + id);
        return null;
    }
	
	public boolean isUpgradable(Item item){
	    String[] row = ruleset_item_upgrade.get(item.getId());
	    if(row == null)
	      return false;
	    return true;
	}

}
